package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.heima.feign.article.IArticleClient;
import com.heima.feign.user.IUserClient;
import com.heima.model.comment.dto.CommentConfigDto;
import com.heima.model.comment.pojos.CommentLike;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.dtos.WmCommentAndRepayDto;
import com.heima.model.wemedia.dtos.WmCommentDto;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.thread.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.pojo.*;
import com.heima.wemedia.service.WmCommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Cvalence
 * @version 1.0
 * @project leadnews-project
 * @date 2024/1/25 09:30:21
 */
@Service
public class WmCommentServiceImpl implements WmCommentService {


    @Qualifier("com.heima.feign.article.IArticleClient")
    @Autowired
    private IArticleClient iArticleClient;
    @Autowired
    private WmNewsMapper wmNewsMapper;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private WmUserMapper wmUserMapper;
    @Autowired
    private IUserClient iUserClient;

    @Override
    public PageResponseResult commentManagementQueries(WmCommentDto wmCommentDto) {
        Integer id = WmThreadLocalUtil.getUser().getId();
        wmCommentDto.setUserId(id);
        System.out.println(id + "-----------------------");
        //通过userID进行判断是否有文章
        QueryWrapper<WmNews> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper
                .apply(wmCommentDto.getBeginDate()!=null, "date(publish_time) >= {0}", wmCommentDto.getBeginDate())
                .apply(wmCommentDto.getEndDate()!=null, "date(publish_time) <= {0}", wmCommentDto.getEndDate())
                .apply(wmCommentDto.getUserId()!=null, "user_id = {0}", wmCommentDto.getUserId());
        /*List<WmNews> wmNews = wmNewsMapper.selectList(Wrappers.lambdaQuery(WmNews.class)
                .eq(WmNews::getUserId, id)
                .between(WmNews::getPublishTime,wmCommentDto.getBeginDate(),wmCommentDto.getEndDate()));*/
        List<WmNews> wmNews = wmNewsMapper.selectList(objectQueryWrapper);
        //new新集合
        ArrayList<Long> list = new ArrayList<>();
        for (WmNews wmNew : wmNews) {
            Long articleId = wmNew.getArticleId();

            list.add(articleId);
        }
        wmCommentDto.setArticleId(list);
        return iArticleClient.getComments(wmCommentDto);
    }

    @Override
    public ResponseResult updateCommentStatus(CommentConfigDto wmUpdateStatusDto) {
//       校验
        if (wmUpdateStatusDto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
//        获得该文章的所有评论
        if (wmUpdateStatusDto.getOperation() == 0) {
            List<ApComment> comments = mongoTemplate.find(Query.query(Criteria.where("entryId").is(wmUpdateStatusDto.getArticleId())), ApComment.class);
            for (ApComment comment : comments) {
//            删除每条评论的点赞
                mongoTemplate.remove(Query.query(Criteria.where("commentId").is(comment.getId())), ApCommentLike.class);
//          删除每条评论的回复
                mongoTemplate.remove(Query.query(Criteria.where("commentId").is(comment.getId())), ApCommentRepay.class);
            }
//        删除所有该文章的评论
            mongoTemplate.remove(Query.query(Criteria.where("entryId").is(wmUpdateStatusDto.getArticleId())), ApComment.class);

        }
//       远程调用修改评论状态
        return iArticleClient.updateCommentStatus(wmUpdateStatusDto);
    }

    @Override
    public ResponseResult list(WmCommentAndRepayDto wmCommentAndRepayDto) {

//        用来返回数据
        List<WmCommentAndRepayVo> wmCommentAndRepayVoList = new ArrayList<>();
//        获得id根据id查询
        Long articleId = wmCommentAndRepayDto.getArticleId();
        Query query1 = Query.query(Criteria.where("entryId").is(articleId));
//        分页查询 和 查询的排序
//        Pageable pageable = PageRequest.of(wmCommentAndRepayDto.getPage(), wmCommentAndRepayDto.getSize());
        Sort createdTime1 = Sort.by(Sort.Direction.DESC, "createdTime");
//        获得按前端传过来的文章id对应的评论集合，且 通过 前端传来的数据分页 和 评论时间（createdTime）的ApComment集合
        List<ApComment> commentList = mongoTemplate.find(query1.with(createdTime1), ApComment.class);
        for (ApComment apComment : commentList) {
            WmCommentAndRepayVo vo = new WmCommentAndRepayVo();
//            单挑评论的id
            String id = apComment.getId();

//            根据评论id查询回复
            Query query2 = Query.query(Criteria.where("commentId").is(id));
            Sort createdTime2 = Sort.by(Sort.Direction.DESC, "createdTime");
            List<ApCommentRepay> commentRepayList = mongoTemplate.find(query2.with(createdTime2), ApCommentRepay.class);
//           封装数据
            vo.setApCommentRepays(commentRepayList);
            vo.setApComments(apComment);
            wmCommentAndRepayVoList.add(vo);
        }

        return ResponseResult.okResult(wmCommentAndRepayVoList);
    }
    /**
     * 删除评论回复功能
     * @param commentRepayId
     * @return
     */
    @Override
    public ResponseResult delCommentRepay(String commentRepayId) {
        //        删除评论的回复评论的点赞
        ApCommentRepay apCommentRepay = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(commentRepayId)), ApCommentRepay.class);
            String apCommentRepayId = apCommentRepay.getId();
            mongoTemplate.remove(Query.query(Criteria.where("commentRepayId").is(apCommentRepayId)), ApCommentAndRepayLike.class);
             String commentId = apCommentRepay.getCommentId();


        ApComment apComment = mongoTemplate.findOne(Query.query(Criteria.where("_id").in(commentId)), ApComment.class);
        Long entryId = apComment.getEntryId();
        Long count = mongoTemplate.count(Query.query(Criteria.where("_id").is(commentRepayId)), ApCommentRepay.class);
        iArticleClient.deletingCommentsReducesComments(entryId, count);
//        删除评论的回复评论
        mongoTemplate.remove(Query.query(Criteria.where("_id").is(commentRepayId)), ApCommentRepay.class);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult delComment(String commentId) {
        ApComment apComment = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(commentId)), ApComment.class);
        Long entryId = apComment.getEntryId();
//        删除评论
        mongoTemplate.remove(Query.query(Criteria.where("_id").is(commentId)), ApComment.class);
//        删除评论的点赞
        mongoTemplate.remove(Query.query(Criteria.where("commentId").is(commentId)), ApCommentLike.class);
//        统计删除一条评论时同时删除的对应的回复评论的数量
        Long count = mongoTemplate.count(Query.query(Criteria.where("commentId").is(commentId)), ApCommentRepay.class);
//       膜一下
        count = count + 1;
        //        删除评论的回复评论的点赞
        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(Query.query(Criteria.where("commentId").is(commentId)), ApCommentRepay.class);
        for (ApCommentRepay apCommentRepay : apCommentRepays) {
            String apCommentRepayId = apCommentRepay.getId();
            mongoTemplate.remove(Query.query(Criteria.where("_id").is(apCommentRepayId)), ApCommentAndRepayLike.class);
        }
//        删除评论的回复评论
        mongoTemplate.remove(Query.query(Criteria.where("commentId").is(commentId)), ApCommentRepay.class);

        iArticleClient.deletingCommentsReducesComments(entryId, count);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 作者点赞操作
     *
     * @param commentLike 评论喜欢
     * @return {@link ResponseResult}
     */
    @Override
    public ResponseResult like(CommentLike commentLike) {
        // 参数校验
        if (commentLike == null && commentLike.getCommentId() == null)
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        // 先查询数据
        ApComment apComment = mongoTemplate.findById(commentLike.getCommentId(), ApComment.class);
        // 获取当前用户登陆的id
        WmUser user = WmThreadLocalUtil.getUser();
        WmUser wmUser = wmUserMapper.selectById(user.getId());

        // 判断用户是否登陆
        if (wmUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 获取用户信息
        ApUser apUser = iUserClient.findUserById(wmUser.getApUserId());
        // 点赞的话，添加点赞数据，新增到点赞的数量
        if (apComment != null && commentLike.getOperation() == 0) {
            // Operation = 0 就是点赞
            apComment.setLikes(apComment.getLikes() + 1);
            mongoTemplate.save(apComment);
            //保存点赞的数据
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setCommentId(apComment.getId());
            apCommentLike.setAuthorId(apUser.getId());
            mongoTemplate.save(apCommentLike);
        }else{
            //取消点赞的操作
            int temp = apComment.getLikes() - 1 < 1 ? 0 : apComment.getLikes();
            apComment.setLikes(temp);
            mongoTemplate.save(apComment);

            //删除评论表中的数据
            Query query = Query.query(Criteria.where("commentId")
                    .is(apComment.getId())
                    .and("authorId")
                    .is(apUser.getId()));
            mongoTemplate.remove(query,ApCommentLike.class);
        }
        //返回剩余点赞数量
        Map<String ,Object> map = new HashMap<>();
        map.put("likes", apComment.getLikes());
        return ResponseResult.okResult(map);
    }
}
